package dk.eclipse.android.badassapp.weapon;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.util.Log;
import dk.eclipse.android.badassapp.preferences.PreferenceHelper;

/**
 * This helper class handles weapon operations and data.
 * 
 * @author Ronni Kahalani (eclipse.dk)
 * 
 */
public class WeaponHelper {
	private static final String FORMAT_WEAPON = "weapon%d";
	/**
	 * Tag used for logging errors.
	 */
	private static final String LOG_TAG = WeaponHelper.class.getSimpleName();
	/**
	 * The weapon database name.
	 */
	public static final String DB_NAME = "badassapp";
	/**
	 * 
	 */
	private static final String ANDROID_DATA_PATH = "/data/data/";
	/**
	 * 
	 */
	private static final String ANDROID_DB_PATH = "/databases/";

	/**
	 * Weapon type index.
	 */
	public static final int WEAPON_KNIFE = 1;
	public static final int WEAPON_CROSSBOW = 2;
	public static final int WEAPON_GUN = 3;
	public static final int WEAPON_MACHINEGUN = 4;
	public static final int WEAPON_HANDGRENATE = 5;
	public static final int WEAPON_RPG = 6;
	public static final int WEAPON_BOMBGUN = 7;
	public static final int WEAPON_JETFIGHTER = 8;
	public static final int WEAPON_SATELLITE = 9;
	public static final int WEAPON_ATOMBOMB = 10;

	/**
	 * Database related constants.
	 */
	private static final String TABLE_WEAPON = "weapon";
	private static final String COLUMN_WEAPON_ID = "weaponId";
	private static final String COLUMN_NAME = "name";
	private static final String COLUMN_DESC = "desc";

	/**
	 * The current context;
	 */
	private static Context context = null;
	/**
	 * The weapon database.
	 */
	private static SQLiteDatabase db = null;

	/**
	 * 
	 */
	private static List<Weapon> weapons = new ArrayList<Weapon>();
	public static String SQL_CREATE_TABLE_WEAPON = "CREATE TABLE IF NOT EXISTS "
			+ TABLE_WEAPON
			+ " ("
			+ COLUMN_WEAPON_ID
			+ " INT(3), "
			+ COLUMN_NAME
			+ " VARCHAR, "
			+ COLUMN_DESC
			+ " VARCHAR);";

	/**
	 * Returns the current context.
	 * 
	 * @return the context
	 */
	public static Context getContext() {
		return context;
	}

	/**
	 * Sets the current context.
	 * 
	 * @param context
	 *            the context to set
	 */
	public static void setContext(Context context) {
		WeaponHelper.context = context;
	}

	/**
	 * Returns the weapons.
	 * 
	 * @return the weapons
	 */
	public static List<Weapon> getWeapons() {
		if (weapons == null) {
			loadWeapons();
		}
		return weapons;
	}

	/**
	 * Returns a weapon sound by resource id.
	 * 
	 * @param index
	 * @return the weapon
	 */
	public static int getSoundId(int index) {
		Resources resources = context.getResources();
		String resourceName = String.format(FORMAT_WEAPON, index);
		int identifier = resources.getIdentifier(resourceName, "raw", context.getPackageName());
		return identifier;
	}

	/**
	 * Returns a weapon image by resource id.
	 * 
	 * @param index
	 * @return the weapon
	 */
	public static int getImageId(int index) {
		Resources resources = context.getResources();
		String resourceName = String.format(FORMAT_WEAPON, index);
		int identifier = resources.getIdentifier(resourceName, "drawable", context.getPackageName());
		return identifier;
	}

	/**
	 * Loads the weapons from the database.
	 */
	public static void loadWeapons() {

		Cursor cursor = null;
		try {
			cursor = db.rawQuery("SELECT * FROM " + TABLE_WEAPON, null);

			if (cursor != null) {
				if (cursor.moveToFirst()) {
					do {
						int weaponId = cursor.getInt(cursor
								.getColumnIndex(COLUMN_WEAPON_ID));

						String name = cursor.getString(cursor
								.getColumnIndex(COLUMN_NAME));
						String desc = cursor.getString(cursor
								.getColumnIndex(COLUMN_DESC));
						
						weapons.add(new Weapon( weaponId, name, desc, getImageId(weaponId), getSoundId(weaponId)));

					} while (cursor.moveToNext());
				}
			}

			

		} catch (SQLiteException se) {
			Log.e(LOG_TAG,
					"Could not create or Open the database");
		} finally {
			if (cursor != null) {
				cursor.close();
			}
		}
	}

	/**
	 * Returns true if the database is available.
	 * 
	 * @param path
	 * @return true if database is available
	 */
	public static boolean isDbAvailable() {
		db = getDb();
		return (db != null);
	}

	/**
	 * Returns the weapon database.
	 * 
	 * @param path
	 * @return the database
	 */
	private static SQLiteDatabase getDb() {

		SQLiteDatabase checkDB = null;

		try {
			checkDB = SQLiteDatabase.openDatabase(getDdPath(), null,
					SQLiteDatabase.OPEN_READWRITE);

		} catch (SQLiteException e) {
			// database does't exist yet.
		}

		return checkDB;
	}

	/**
	 * Creates a new weapon database.
	 * 
	 * @param dbName
	 * @return the new database
	 */
	private static SQLiteDatabase createDb(String dbName) {

		db = context.openOrCreateDatabase(dbName, Context.MODE_PRIVATE, null);
		db.execSQL(WeaponHelper.SQL_CREATE_TABLE_WEAPON);

		insertWeapon(new Weapon(WEAPON_KNIFE, "Knife", "Light, silent and effective"));
		insertWeapon(new Weapon(WEAPON_CROSSBOW, "Crossbow", "No noice, just a fast hit"));
		insertWeapon(new Weapon(WEAPON_GUN, "Gun", "Good for making small simple holes"));
		insertWeapon(new Weapon(WEAPON_MACHINEGUN, "Machinegun", "Ahhh, now we are talking, da da da"));
		insertWeapon(new Weapon(WEAPON_HANDGRENATE, "Handgrenade", "Nasty, beware of the metal splinters"));
		insertWeapon(new Weapon(WEAPON_RPG, "Rocket Propelled Grenade",	"Will take down a tank, if you are lucky"));
		insertWeapon(new Weapon(WEAPON_BOMBGUN, "Bombgun", "Kaboooom, amazing holes this gadget can do, wow"));
		insertWeapon(new Weapon(WEAPON_JETFIGHTER, "Jet Fighter", "Yeaaah, lots of fun and serious damage"));
		insertWeapon(new Weapon(WEAPON_SATELLITE, "Satellite", "With eyes on the world, you will be the king...or queen"));
		insertWeapon(new Weapon(WEAPON_ATOMBOMB, "Atomic Bomb", "Why not go all the way...remember sun glasses"));

		return db;
	}

	/**
	 * Loads the weapons from the database, and creates the database if not
	 * found.
	 * 
	 * @param context
	 */
	public static void loadDatabase() {

		weapons.clear();

		if (db == null) {
			db = getDb();
			if (db == null) {
				Log.i(LOG_TAG, "Creating weapon new database: " + DB_NAME);
				db = createDb(DB_NAME);
			}
		}

		loadWeapons();
		Log.i(LOG_TAG, "Loaded number of weapons: " + weapons.size());
		closeDatabase();
		PreferenceHelper.setCreateDatabase(context, false);

	}

	/**
	 * Returns the database path.
	 * 
	 * @param context
	 * @return the path
	 */
	private static String getDdPath() {
		String dbFolder = ANDROID_DATA_PATH + context.getPackageName()
				+ ANDROID_DB_PATH;

		return dbFolder + DB_NAME;
	}

	/**
	 * Inserts a new weapon into the database.
	 * 
	 * @param weapon
	 */
	private static void insertWeapon(Weapon weapon) {
		db.execSQL(String.format("INSERT INTO %s VALUES (%d,'%s','%s');", TABLE_WEAPON, weapon.getWeaponId(), weapon.getName(), weapon.getDesc()));
	}

	/**
	 * Close database
	 */
	public static void closeDatabase() {

		if (db != null) {
			db.close();
			db = null;
		}
	}

	/**
	 * Deletes the weapon database.
	 * 
	 * @return true if the database was deleted.
	 */
	public static boolean deleteDb() {
		closeDatabase();
		boolean deleted = context.deleteDatabase(WeaponHelper.DB_NAME);
		Log.i(LOG_TAG, "Database deleted: " + deleted);

		return deleted;
	}

}
